package com.java.activiti.service.impl;

import com.alibaba.fastjson.JSON;
import com.java.activiti.service.ActivityCommonService;
import com.java.activiti.util.StringUtil;
import lombok.extern.slf4j.Slf4j;
import org.activiti.engine.*;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.repository.DeploymentBuilder;
import org.activiti.engine.repository.DeploymentQuery;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.runtime.Execution;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Map;
import java.util.zip.ZipInputStream;

/**
 * @Company: PcGroup.ltd
 * @Author: wei.ye
 * @Date: 2021/1/12 15:30
 * @Modified:2021/1/12 15:30
 * @Description:
 */
@Slf4j
@Transactional(propagation=Propagation.REQUIRED,timeout=10,readOnly = false)
@Service
public class ActivityCommonServiceImpl implements ActivityCommonService{
    @Autowired
    private RepositoryService repositoryService;
    @Autowired
    private RuntimeService runtimeService;
    @Autowired
    private TaskService taskService;
    @Autowired
    private HistoryService historyService;
    @Autowired
    private IdentityService identityService;
    /**
     * 发布服务 RepositoryService
     *
     * @param inputStream
     * @param resourceName
     * @param deployName
     * @return Deployment 部署后的对象信息
     */
    @Override
    public Deployment deploy(ZipInputStream inputStream, String resourceName, String deployName, String text,String category) {

        if(inputStream==null){
            log.error("获取发布文件失败...", new RuntimeException("获取发布文件失败..."));
            return null;
        } else {
            DeploymentBuilder deploymentBuilder = repositoryService.createDeployment().addZipInputStream(inputStream).name(deployName).category(category).addString(resourceName, text);
            Deployment deployment = deploymentBuilder.deploy();
            return deployment;
        }

    }

    /**
     * 通过 ProcessInstanceId启动流程
     *
     * @param deploymentId
     * @param paramas             启动流程时自带的参数
     * @return
     */
    @Override
    public ProcessInstance startProcessInstanceWithId(String deploymentId, Map<String, Object> paramas) {
        ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().deploymentId(deploymentId).singleResult();
        //利用act_re_procdef 的id_来进行部署
        ProcessInstance processInstance = runtimeService.startProcessInstanceById(processDefinition.getId(), paramas);
        return processInstance;
    }

    /**
     * 任务办理时设置流程变量
     *
     * @param task
     * @param paramas
     * @param comment
     * @param args
     * @return
     */
    @Override
    public boolean completeTask(Task task, Map<String, Object> paramas, String comment, Object... args) {
        if(StringUtils.isBlank(task.getId())) {
            log.info("error:taskid不存在");
            return false;
        }else if(task.isSuspended()){
            runtimeService.startProcessInstanceById(task.getProcessDefinitionId(), paramas);
            return false;
        }else {
            //任务办理时设置流程变量
            taskService.complete(task.getId(),paramas);
            log.info("已经over的步骤task:taskid="+task.getId()+",name:"+task.getName()+",ProcessDefinitionId("+task.getProcessDefinitionId()+",ProcessInstanceId"+task.getProcessInstanceId());
        }
        return true;
    }

    /**
     * 通过流程实例id设置流程变量并完成当前步骤
     * @param task
     * @param executionId
     * @param paramas
     * @param comment
     * @param args
     * @return
     */
    @Override
    public boolean completeTask(Task task, String executionId, Map<String, Object> paramas, String comment, Object... args) {
        //通过当前流程实例设置 act_ru-execution表
        runtimeService.setVariables(executionId,paramas);
        if(StringUtils.isBlank(task.getId())) {
            log.info("error:taskid不存在");
            return false;
        }else if(task.isSuspended()){
            runtimeService.startProcessInstanceById(task.getProcessDefinitionId());
            return false;
        }else {

            taskService.complete(task.getId());
            log.info("已经over的步骤task:taskid="+task.getId()+",name:"+task.getName()+",ProcessDefinitionId("+task.getProcessDefinitionId()+",ProcessInstanceId"+task.getProcessInstanceId());
        }
        return true;
    }

    /**
     * runtimeServie通过processDefinitionId获得唯一的ProcessInstance
     *
     * @param processDefinitionId
     * @param args                processInstanceId以外的参数
     * @return
     */
    @Override
    public ProcessInstance createProcessInstanceByprocessDefinitionId(String processDefinitionId, String... args) {
        //查询当前运行的实例 用name就ok
        ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processDefinitionId(processDefinitionId).processDefinitionName(args[0]).singleResult();
        return processInstance;
    }

    /**
     * runtimeServie通过processDefinitionId获得ProcessInstance集合
     *
     * @param processDefinitionId
     * @param args                processInstanceId以外的参数非必须
     * @return
     */
    @Override
    public List<ProcessInstance> createProcessInstanceListByprocessDefinitionId(String processDefinitionId, String... args) {
        List<ProcessInstance> instanceList = runtimeService.createProcessInstanceQuery().processDefinitionId(processDefinitionId).processDefinitionName(args[0]).list();
        return instanceList;
    }

    /**
     * taskService 通过processDefinitionID 获得唯一的task
     *
     * @param processDefinitionId
     * @param args                processDefinitionId以外的其他参数非必须
     * @return
     */
    @Override
    public Task createTaskQueryByprocessDefinitionId(String processDefinitionId, String... args) {
        Task task = taskService.createTaskQuery().processDefinitionId(processDefinitionId).processInstanceId(args[0]).singleResult();
        return task;
    }

    /**
     * taskService 通过processDefinitionID 获得唯一的task
     *
     * @param processDefinitionId
     * @param args                processDefinitionId以外的其他参数非必须
     * @return
     */
    @Override
    public List<Task> createTaskListQueryByprocessDefinitionId(String processDefinitionId, String... args) {
        List<Task> taskList = taskService.createTaskQuery().processDefinitionId(processDefinitionId).processInstanceId(args[0]).list();
        return taskList;
    }

    /**
     * RepositoryService 查询
     *
     * @param deployName
     * @param deployId
     * @return
     */
    @Override
    public Deployment createDeploymentQueryByName(String deployName, String deployId,String categroy) {
        DeploymentQuery deploymentQuery = repositoryService.createDeploymentQuery();
        if(StringUtils.isNotBlank(deployName)) {
            deploymentQuery.deploymentNameLike(deployName.trim());
        }else if(StringUtils.isNotBlank(deployId)){
            deploymentQuery.deploymentId(deployId);
        } else if(StringUtils.isNotBlank(categroy)){
            deploymentQuery.deploymentCategory(categroy);
        }
        Deployment deployment = deploymentQuery.singleResult();
        return deployment;
    }

    /**
     * RepositoryService 查询
     *
     * @param deployName
     * @param deployId
     * @param args
     * @return
     */
    @Override
    public List<Deployment> createDeploymentListQueryByName(String deployName, String deployId, String... args) {
        List<Deployment> listDeployment = repositoryService.createDeploymentQuery().deploymentName(deployName).deploymentId(deployId).deploymentCategory(args[0]).list();
        return listDeployment;
    }

    /**
     * 通过repositoryService 传递processDefinationKey来做查询
     * @param processDefinationKey
     * @return
     */
    @Override
    public ProcessDefinition getCurrentProcessDefination(String processDefinationKey) {
        ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().processDefinitionKeyLike(processDefinationKey).singleResult();
        return processDefinition;
    }

    /**
     * 通过processDefinationId和 责任人assignee去获得当前责任人的task信息
     *
     * @param processDefinationId
     * @param assignee
     * @return
     */
    @Override
    public  List<Task>  getCurrentTaskInstance(String processDefinationId, String assignee) {
        List<Task> taskList = taskService.createTaskQuery().taskAssignee(assignee).processDefinitionId(processDefinationId).list();
        return taskList;
    }

    /**
     * 通过assignee和processDefinationkey来获得属于当前责任人的task act_re_prodef-->act_ru_execution-->
     * act_ru_task
     *
     * @param queryParas :assignee,processDefinationKey
     * @return
     */
    @Override
    public List<Task> findUniqueRuntimeTaskByAssigneeAndprocessDefinationKey(Map<String, Object> queryParas) {
        //1.act_re_procedef     获得其id
        ProcessDefinition processDefination = repositoryService.createProcessDefinitionQuery().processDefinitionKey(queryParas.get("processDefinationKey").toString()).singleResult();
        //3.查询当前责任人的待办信息
        List<Task> taskList = taskService.createTaskQuery().taskAssignee(queryParas.get("assignee").toString()).processDefinitionId(processDefination.getId()).list();
        return taskList;
    }
}


